﻿/*************************************
 * Creator:SW-PeiYang
 * DateTime:2023/12/8 9:58:08
 * Description:<Description>
 * CopyRight:中广核研究院有限公司
 * ***********************************/

using Cpjit.SunnyPaine.Toolkit.Net.Sockets.Model;
using System;
using System.Collections.Generic;
using System.Net.Sockets;

namespace Cpjit.SunnyPaine.Toolkit.Net.Sockets.IDataHandlingApdapter
{
    /// <summary>
    /// 表示处理Socket消息的处理适配器的公共抽象逻辑。
    /// </summary>
    public abstract class AbstractDataHandlingApdapter : IDataHandlingAdapter
    {
        #region 保护变量
        /// <summary>
        /// 处理器是否工作。
        /// </summary>
        protected bool isRunning = false;
        /// <summary>
        /// 处理数据的缓存。
        /// </summary>
        protected ByteBlock tempData;
        /// <summary>
        /// 最后缓存数据的时间。
        /// </summary>
        protected DateTime lastCacheTime;
        /// <summary>
        /// 缓存数据的超时时长。
        /// </summary>
        protected TimeSpan cacheTimeout = new TimeSpan(0, 0, 1);
        #endregion


        #region 公共属性
        /// <summary>
        /// 是否启用消息缓存超时。默认false。
        /// </summary>
        public bool UseCacheTime { get; set; }
        /// <summary>
        /// 缓存大小。默认<see cref="ushort.MaxValue"/>。
        /// </summary>
        public int Capacity { get; protected set; } = ushort.MaxValue;
        #endregion


        #region 委托事件
        /// <summary>
        /// 当接收的数据处理完成后发生。
        /// </summary>
        public event Action<SocketSession, byte[]> GoReceived;
        /// <summary>
        /// 当发送的数据处理完成后发生。
        /// </summary>
        public event Action<Socket, byte[], bool> GoSend;
        #endregion


        #region 公共方法，IDataHandlingAdapter成员
        /// <summary>
        /// 消息接收前处理。
        /// </summary>
        /// <param name="session"></param>
        public abstract void PreviewReceived(SocketSession session);

        /// <summary>
        /// 消息发送前处理。
        /// </summary>
        /// <param name="remote">远端Socket实例。</param>
        /// <param name="datas">要发送的数据。</param>
        /// <param name="isAsync">是否异步发送。true：异步，false：同步。</param>
        public virtual void PreviewSend(Socket remote, byte[] datas, bool isAsync)
        {
            this.GoSendHandle(remote, datas, isAsync);
        }

        /// <summary>
        /// 消息发送前处理。
        /// </summary>
        /// <param name="remotes">远端Socket实例。</param>
        /// <param name="datas">要发送的数据。</param>
        /// <param name="isAsync">是否异步发送。true：异步，false：同步。</param>
        public virtual void PreviewSend(List<Socket> remotes, byte[] datas, bool isAsync)
        {
            foreach (Socket remote in remotes)
            {
                this.GoSendHandle(remote, datas, isAsync);
            }
        }

        /// <summary>
        /// 停止处理器并释放所有处理器的资源。
        /// </summary>
        public virtual void Dispose()
        {
            this.isRunning = false;
            this.tempData?.Reset();
            this.tempData = null;
        }
        #endregion


        #region 保护方法
        /// <summary>
        /// 执行GoReceived委托。
        /// </summary>
        /// <param name="session"></param>
        /// <param name="data"></param>
        protected void GoReceivedHandle(SocketSession session, byte[] data)
        {
            this.GoReceived?.Invoke(session, data);
        }

        /// <summary>
        /// 执行GoSend委托。
        /// </summary>
        /// <param name="remote"></param>
        /// <param name="data"></param>
        /// <param name="isAsync"></param>
        protected void GoSendHandle(Socket remote, byte[] data, bool isAsync)
        {
            this.GoSend?.Invoke(remote, data, isAsync);
        }
        #endregion
    }
}
